/**
 * ISC License
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

"use strict";

import xml from "@ohos/xmpp_xml";

/*
 * References
 * https://xmpp.org/rfcs/rfc6120.html#bind
 */

const NS = "urn:ietf:params:xml:ns:xmpp-bind";

function makeBindElement(resource) {

    return xml("bind", { xmlns: NS }, resource && xml("resource", {}, resource));
}

async function bind(entity, iqCaller, resource) {
  const result = await iqCaller.set(makeBindElement(resource));
  const jid = result.getChildText("jid");
  entity._jid(jid);
  return jid;
}

function route({ iqCaller }, resource) {
    return async ({ entity }, next) => {
        await (typeof resource === "function"
            ? resource((resource) => bind(entity, iqCaller, resource))
            : bind(entity, iqCaller, resource));
        next();
    };
}

export default function resourceBinding(
    { streamFeatures, iqCaller },
    resource,
) {
    streamFeatures.use("bind", NS, route({
        iqCaller
    }, resource));
};
